package com.xsprite.managesys.dao;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.xsprite.managesys.bean.ItemLog;
import com.xsprite.managesys.bean.LoginlogRecord;
import com.xsprite.managesys.bean.Page;
import com.xsprite.managesys.bean.Player;
import com.xsprite.managesys.bean.PlayerInfoLog;
import com.xsprite.managesys.bean.PlayerLog;
import com.xsprite.managesys.bean.QueryRoleInfo;
import com.xsprite.managesys.bean.QueryServer;
import com.xsprite.managesys.bean.Role;
import com.xsprite.managesys.log.LogManager;

public class MyBatisDao {
	private Map<Integer, SqlSessionFactory> factoryMap = new HashMap<Integer, SqlSessionFactory>();
	
	public void loadFactories(List<QueryServer> serversList, String batisPath) throws FileNotFoundException{
		for(QueryServer server : serversList){
			InputStream is = new FileInputStream(batisPath);
	        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is, server.getLogDBId() + "");
	        factoryMap.put(server.getLogDBId(), sessionFactory);
	        is = new FileInputStream(batisPath);
	        SqlSessionFactory sessionFactory2 = new SqlSessionFactoryBuilder().build(is, server.getGameDBId() + "");
	        factoryMap.put(server.getGameDBId(), sessionFactory2);
	        LogManager.getInstance().log4j("load factory : " + server.getLogDBId());
		}
		LogManager.getInstance().log4j("load factories finished : " + factoryMap.size());
	}
	
	private long getRoleIdByRoleName(int serverid, String playerName){
		SqlSessionFactory factory = factoryMap.get(serverid);
		if(factory != null){
			SqlSession session = null;
			session = factory.openSession();
			String statement = "me.gacl.mapping.itemLogMapper.getRoleId";//映射sql的标识字符串
			Role role = new Role();
			role.setRolename(playerName);
			Role r = (Role) session.selectOne(statement, role);
			if(session != null){
				session.close();
			}
			return r.getRoleid();
		}
		return -1;
	}
	
	public List<ItemLog> queryEmail(int serverid, int logDbid, String playerName, String toQueryTable, String userid){
		long roleid = getRoleIdByRoleName(serverid, playerName);
		if(roleid == -1){
			LogManager.getInstance().log4j("userid = " + userid + " 沒有找到roleid[" + playerName + "]");
			return null;
		}
		 SqlSessionFactory factory = factoryMap.get(logDbid);
		 if(factory != null){
			 SqlSession session = null;
			 try{
				 session = factory.openSession();
				 String statement = "me.gacl.mapping.itemLogMapper.getItemLogs";//映射sql的标识字符串
				 ItemLog log = new ItemLog();
				 log.setName("%" + roleid + "%");
				 log.setToqueryTable(toQueryTable);
				 List<ItemLog> itemLogs = session.selectList(statement, log);
				 return itemLogs;
			 } catch (Exception ex){
				 LogManager.getInstance().log4j("userid = " + userid + " 表" + toQueryTable + "不存在(" + playerName + ")");
				 throw new RuntimeException(ex);
			 } finally {
				if(session != null){
					session.close();
				}
			}
		 }
		 return null;
	}
	
	public List<PlayerInfoLog> queryPlayerInfoLog(int serverId, int logDbid, String userid, PlayerInfoLog playerInfoLog){
		long roleid = getRoleIdByRoleName(serverId, playerInfoLog.getPlayerName());
		if(roleid == -1){
			LogManager.getInstance().log4j("userid = " + userid + " 沒有找到roleid[" + playerInfoLog.getPlayerName() + "]");
			return null;
		}
		SqlSessionFactory factory = factoryMap.get(logDbid);
		if(factory != null){
			SqlSession session = null;
			try{
				session = factory.openSession();
				String statement = "me.gacl.mapping.itemLogMapper.getPlayerInfoLog";
				List<PlayerInfoLog> playerInfoLogs = session.selectList(statement, playerInfoLog);
				return playerInfoLogs;
			} catch (Exception ex){
				LogManager.getInstance().log4j("userid = " + userid + " 表" + playerInfoLog.getToQueryTable() + "不存在(" + playerInfoLog.getPlayerName() + ")" + ex.getMessage());
//				throw new RuntimeException(ex);
				return null;
			} finally {
				if(session != null){
					session.close();
				}
			}
		}
		return null;
	}
	
	public List<LoginlogRecord> queryEverydayLogin(int logDbid, List<PlayerLog> playerLogs){
		SqlSessionFactory factory = factoryMap.get(logDbid);
		List<LoginlogRecord> records = new ArrayList<LoginlogRecord>();
		for(PlayerLog pl : playerLogs){
			Integer thisDayLoginCount = 0;
			if(factory != null){
				SqlSession session = null;
				try{
					session = factory.openSession();
					String statement = "me.gacl.mapping.itemLogMapper.getEverydayLoginCount";
					thisDayLoginCount = (Integer)session.selectOne(statement, pl);
					records.add(new LoginlogRecord(pl.getToqueryTable(), thisDayLoginCount));
				} catch (Exception ex){
					if(ex.getMessage().indexOf("doesn't exist") != -1){
						records.add(new LoginlogRecord(pl.getToqueryTable(), 0));
					}
					ex.printStackTrace();
				} finally {
					if(session != null){
						session.close();
					}
				}
			}
		}
		return records;
	}
	
	
	public List<Player> queryStasticPlayers(int gameDbId){
		SqlSessionFactory factory = factoryMap.get(gameDbId);
		List<Player> totalPlayers = new ArrayList<Player>();
		if(factory != null){
			SqlSession session = null;
			try{
				session = factory.openSession();
				String statement = "me.gacl.mapping.itemLogMapper.getCountOfRole";
				Integer roleCount = (Integer) session.selectOne(statement);
				int pageCount = calculatePage(roleCount);
				for(int i = 0; i < pageCount; i++){
					Page page = new Page();
					page.setStart(i * OFFSET);
					page.setCount(OFFSET);
					List<Player> pagePlayers = queryPlayerStasticsByPage(session, page);
					totalPlayers.addAll(pagePlayers);
					System.out.println("第" + (i + 1) + "页," + pagePlayers.size() + "个玩家");
					 Thread.sleep(1500);
				}
			} catch (Exception ex){
				ex.printStackTrace();
			} finally {
				if(session != null){
					session.close();
				}
			}
		}
		return totalPlayers;
	}
	
	public List<Player> queryPlayers(int gameDbId){
		SqlSessionFactory factory = factoryMap.get(gameDbId);
		List<Player> totalPlayers = new ArrayList<Player>();
		if(factory != null){
			SqlSession session = null;
			try{
				session = factory.openSession();
				String statement = "me.gacl.mapping.itemLogMapper.getCountOfRole";
				Integer roleCount = (Integer) session.selectOne(statement);
				int pageCount = calculatePage(roleCount);
				for(int i = 0; i < pageCount; i++){
					 Page page = new Page();
					 page.setStart(i * OFFSET);
					 page.setCount(OFFSET);
					 List<Player> pagePlayers = queryByPage(session, page);
					 totalPlayers.addAll(pagePlayers);
					 System.out.println("第" + (i + 1) + "页," + pagePlayers.size() + "个玩家");
					 Thread.sleep(1500);
				}
				
			} catch (Exception ex){
				ex.printStackTrace();
			} finally {
				if(session != null){
					session.close();
				}
			}
		}
		return totalPlayers;
	}
	
	private final int OFFSET = 500;
	
	private int calculatePage(int totalCount){
		if(totalCount % OFFSET == 0){
			return totalCount / OFFSET;
		} else {
			return totalCount / OFFSET + 1;
		}
	}
	
	private List<Player> queryPlayerStasticsByPage(SqlSession session, Page page){
		String statement = "me.gacl.mapping.itemLogMapper.getPlayerStasticsByPage";
		List<Player> players = session.selectList(statement, page);
		return players;
	}
	
	private List<Player> queryByPage(SqlSession session, Page page){
		String statement = "me.gacl.mapping.itemLogMapper.getRolesByPage";
		List<Player> players = session.selectList(statement, page);
		return players;
	}
	
	public QueryRoleInfo queryRoleInfo(int gameDbId, String playerName){
		SqlSessionFactory factory = factoryMap.get(gameDbId);
		if(factory != null){
			SqlSession session = null;
			session = factory.openSession();
			String statement = "me.gacl.mapping.itemLogMapper.getRoleInfoWithName";
			QueryRoleInfo queryUserInfo = (QueryRoleInfo) session.selectOne(statement, playerName);
			if(session != null){
				session.close();
			}
			return queryUserInfo;
		}
		return null;
	}
}